from flask import request, jsonify
from api.db.services.track_service import TrackService
from api.db.services.QuestionClusterer import QuestionClusterer  # 替换为实际路径
import threading
import time
from datetime import datetime
from flask_login import login_required

# 全局聚类器实例
clusterer = QuestionClusterer()

@manager.route('/link_test', methods=['GET'])
def link_test():
    return get_json_result(data='link test success')

@manager.route('/save_question', methods=['POST'])
def save_question():
    data = request.json
    try:
        question_id = TrackService.save_question(
            anonymous_user_id=data.get('anonymous_user_id'),
            login_user_email=data.get('login_user_email'),
            conversation_id=data.get('conversation_id'),
            timestamp=data.get('timestamp'),
            question=data['question']
        )
        return get_json_result(data={"question_id": str(question_id)})
    except Exception as e:
        return get_data_error_result(data=False, message=str(e), code=500)

@manager.route('/update_answer', methods=['POST'])
def update_answer():
    data = request.json
    try:
        TrackService.update_answer(
            question_id=data['question_id'],
            answer=data['answer']
        )
        return get_json_result(data=True)
    except Exception as e:
        return get_data_error_result(data=False, message=str(e), code=500)

@manager.route('/get_questions', methods=['POST'])
def get_questions():
    data = request.json
    try:
        anonymous_user_id = data.get('anonymous_user_id')
        login_user_email = data.get('login_user_email')
        start_date = data.get('start_date')
        end_date = data.get('end_date')
        page = int(data.get('page', 1))
        page_size = int(data.get('page_size', 10))
        
        # 转换时间范围
        start_ts = convert_to_timestamp(start_date) if start_date else None
        end_ts = convert_to_timestamp(end_date) if end_date else None
        
        query = TrackService.get_questions(
            anonymous_user_id=anonymous_user_id,
            login_user_email=login_user_email,
            start_timestamp=start_ts,
            end_timestamp=end_ts
        )
        total = query.count()
        questions = query.paginate(page, page_size).dicts()
        return get_json_result(data={
            'list': list(questions),
            'total': total,
            'page': page,
            'page_size': page_size
        })
    except Exception as e:
        return get_data_error_result(data=[], message=str(e))

# 新增的聚类相关路由

@manager.route('/cluster/run_full', methods=['POST'])
@login_required
def run_full_clustering():
    """全量重新聚类（删除旧聚类，处理半年数据）"""
    try:
        threading.Thread(target=clusterer.run_clustering, kwargs={'mode': 'full'}, daemon=True).start()
        return get_json_result(data=True, message="全量聚类任务已开始执行")
    except Exception as e:
        return get_data_error_result(data=False, message=str(e), code=500)

@manager.route('/cluster/run_range', methods=['POST'])
@login_required
def run_range_clustering():
    """按时间范围聚类（删除旧聚类，处理指定时间范围数据）"""
    data = request.json
    try:
        start_date = data.get('start_date')  # 可以是时间戳或日期字符串
        end_date = data.get('end_date')      # 可以是时间戳或日期字符串
        
        # 转换日期格式为时间戳（毫秒级）
        start_ts = convert_to_timestamp(start_date)
        end_ts = convert_to_timestamp(end_date)
        
        # 验证时间范围
        if start_ts > end_ts:
            return get_data_error_result(data=False, message="开始时间不能晚于结束时间", code=400)
        
        threading.Thread(
            target=clusterer.run_clustering,
            kwargs={'mode': 'range', 'time_range': (start_ts, end_ts)},
            daemon=True
        ).start()
        return get_json_result(data=True, message="时间范围聚类任务已开始执行")
    except Exception as e:
        return get_data_error_result(data=False, message=str(e), code=500)

@manager.route('/cluster/run_incremental', methods=['POST'])
@login_required
def run_incremental_clustering():
    """增量聚类（保留旧聚类，处理新增数据）"""
    try:
        threading.Thread(
            target=clusterer.run_clustering,
            kwargs={'mode': 'incremental'},
            daemon=True
        ).start()
        return get_json_result(data=True, message="增量聚类任务已开始执行")
    except Exception as e:
        return get_data_error_result(data=False, message=str(e), code=500)

@manager.route('/cluster/start_scheduler', methods=['POST'])
@login_required
def start_cluster_scheduler():
    """启动定时聚类任务"""
    data = request.json
    try:
        interval = int(data.get('interval_minutes', 60))  # 默认60分钟
        
        if clusterer.running:
            return get_json_result(data=False, message="调度器已在运行中", code=200)
            
        clusterer.start_scheduler(interval_minutes=interval)
        return get_json_result(data=True, message=f"已启动定时聚类任务，间隔: {interval}分钟")
    except Exception as e:
        return get_data_error_result(data=False, message=str(e), code=500)

@manager.route('/cluster/stop_scheduler', methods=['POST'])
@login_required
def stop_cluster_scheduler():
    """停止定时聚类任务"""
    try:
        if not clusterer.running:
            return get_json_result(data=False, message="调度器未运行", code=200)
            
        clusterer.stop_scheduler()
        return get_json_result(data=True, message="已停止定时聚类任务")
    except Exception as e:
        return get_data_error_result(data=False, message=str(e), code=500)

@manager.route('/cluster/status', methods=['GET'])
@login_required
def get_cluster_status():
    """获取聚类任务状态"""
    try:
        return get_json_result(data={
            'is_running': clusterer.running,
            'is_locked': clusterer.lock.locked()
        })
    except Exception as e:
        return get_data_error_result(data=False, message=str(e), code=500)

@manager.route('/cluster/list', methods=['POST'])
@login_required
def get_clusters_list():
    """获取聚类结果列表"""
    data = request.json
    try:
        user_identifier = data.get('user_identifier')  # 用户标识
        conversation_id = data.get('conversation_id')  # 会话标识
        page = int(data.get('page', 1))
        page_size = int(data.get('page_size', 10))

        query = clusterer.get_clusters_by_user(user_identifier=user_identifier,conversation_id=conversation_id,page=page,page_size=page_size)
        return get_json_result(data=query)

    except Exception as e:
        return get_data_error_result(data=False, message=str(e),code=500)

@manager.route('/cluster/top_questions', methods=['POST'])
def get_top_questions():
    """获取用户最常见问题的前三个聚类"""
    data = request.json
    try:
        user_identifier = data.get('user_identifier')  # 用户标识 必填
        conversation_id = data.get('conversation_id')  # 会话标识 选填
        if not user_identifier:
            return get_json_result( message="用户标识不存在")
        top_questions = clusterer.get_top_clusters_by_user(user_identifier=user_identifier,conversation_id=conversation_id)
        return get_json_result(data=top_questions)
    except Exception as e:
        return get_data_error_result(data=False, message=str(e),code=500)

def get_json_result(code=0, message="success", data=None):
    response = {"code": code, "message": message, "data": data}
    return jsonify(response)

def get_data_error_result(code=500, message=None, data=None):
    response = {"code": code, "message": message, "data": data}
    return jsonify(response)

def convert_to_timestamp(date_input):
    """将日期字符串或时间戳转换为Unix时间戳（毫秒级）"""
    if isinstance(date_input, (int, float)):
        # 如果已经是时间戳，直接返回
        return int(date_input)
    elif isinstance(date_input, str):
        try:
            # 尝试解析ISO格式日期字符串
            dt = datetime.fromisoformat(date_input.replace('Z', '+00:00'))
            return int(dt.timestamp() * 1000)  # 转换为毫秒级时间戳
        except ValueError:
            # 尝试解析其他常见格式
            try:
                dt = datetime.strptime(date_input, "%Y-%m-%d")
                return int(dt.timestamp() * 1000)
            except ValueError:
                raise ValueError(f"无法解析日期格式: {date_input}")
    else:
        raise TypeError("输入必须是字符串或数字时间戳")

# 保持主线程运行的函数（如果需要在后台运行）
def run_background_clusterer():
    """后台运行聚类服务"""
    # 示例：启动时立即运行一次
    clusterer.run_clustering()
    
    # 然后每小时运行一次
    clusterer.start_scheduler(interval_minutes=60)
    
    # 保持主线程运行
    while True:
        time.sleep(1)

# 如果需要后台运行，取消下面注释
# if __name__ == "__main__":
#     background_thread = threading.Thread(target=run_background_clusterer, daemon=True)
#     background_thread.start()
#     manager.run()  # 启动Flask应用